#ifndef FILTERMODEL_H
#define FILTERMODEL_H

#include "imodel.h"
#include <QList>
#include <QSharedPointer>
#include <QSortFilterProxyModel>

/**
 * CFilterModel 类继承自 QSortFilterProxyModel，用于提供一种自定义的过滤模型。
 */
class CFilterModel:public QSortFilterProxyModel
{
    Q_OBJECT
public:
    /**
     * 构造函数
     * @param parent 父对象，默认为 nullptr
     */
    CFilterModel(QObject *parent = nullptr);

    /**
     * 应用新的过滤条件到某个字段。
     * @param newFilterField 指定要应用过滤条件的字段名。
     * @param newFilterContent 过滤条件的内容。
     * 该函数不返回任何值，其主要作用是为指定的字段应用新的过滤条件。
     */
    void applyFilter(const QString &newFilterField, const QString &newFilterContent);

    void applyFilter(QList<QPair<QString,QString>> filterList);

    // 以下为自定义信号，用于通知过滤条件的变化和匹配情况
    QList<QPair<QString, QString> > filterList() const;

    /**
     * 设置过滤器列表。
     * @param filterList 过滤器列表，包含一对 QString 对象，用于指定过滤条件。
     */
    void setFilterList(const QList<QPair<QString, QString> > &filterList);

    /**
     * 清除当前设置的所有过滤器。
     */
    void clearFilter();

    QString sortField() const;
    void setSortField(const QString &sortField);

signals:
    /**
     * 当某一行匹配过滤条件时发出的信号。
     * @param index 匹配的模型索引
     */
    void filterMatched(const QModelIndex &index) const;

    // 以下为自定义的过滤逻辑实现
protected:
    /**
     * 决定是否接受源模型的某一行。
     * @param source_row 源模型的行号
     * @param source_parent 源模型的父索引
     * @return 如果行符合过滤条件，则返回 true，否则返回 false
     */
    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;

    /**
    * 尝试设置给定模型索引处的数据。
    *
    * @param index 指向要设置数据的模型项的索引。
    * @param value 要设置的新数据。
    * @param role 指定数据的角色（用途）。
    * @return 如果成功设置数据则返回true，否则返回false。
    */
    bool setData(const QModelIndex &index, const QVariant &value, int role);

    /**
     * 比较两个模型索引对象的顺序。
     * 
     * 该函数用于比较指定的两个模型索引对象（source_left 和 source_right），
     * 以确定它们在排序视图中的顺序。这通常用于自定义模型的排序逻辑。
     *
     * @param source_left  第一个要比较的模型索引对象。
     * @param source_right 第二个要比较的模型索引对象。
     * @return 返回一个布尔值，如果 source_left 应该排在 source_right 之前，则返回 true；
     *         否则，如果 source_left 和 source_right 相等，或 source_left 应该排在 source_right 之后，
     *         返回 false。
     */
    bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;

private:
    /**
     * 判断给定索引的行是否匹配过滤条件。
     * @param index 被检查的模型索引
     * @return 如果匹配过滤条件，则返回 true，否则返回 false
     */
    bool matchesFilter(const QModelIndex &index) const;

    /**
     * 判断给定索引的行是否有匹配过滤条件的后代。
     * @param index 被检查的模型索引
     * @return 如果有后代匹配过滤条件，则返回 true，否则返回 false
     */
    bool hasMatchingDescendant(const QModelIndex &index) const;

    /**
     * 清除过滤器列表中的所有条目。
     */
    void clearFilterList(){m_filterList.clear();}

    /**
     * 向过滤器列表中添加一个新过滤器。
     * 
     * @param filter 一个包含两个QString元素的QPair，通常用于表示过滤条件的关键字和值。
     */
    void addFilter(QPair<QString,QString> filter);

    //过滤条件为空
    bool filterIsEmpty() const;

private:
    // 存储过滤器的列表，每个过滤器由一对关键字和值组成。
    QList<QPair<QString,QString>> m_filterList;
    QString m_sortField;
};

#endif // FILTERMODEL_H
